package components

import (
	"web/actions"
	"web/store"
	"github.com/gopherjs/vecty/prop"

	v "github.com/gopherjs/vecty"
	"github.com/gopherjs/vecty/elem"
	"github.com/gopherjs/vecty/event"
	"marwan.io/vstore"
)


type Dialog struct {
	v.Core
	Show        bool                `vecty:"prop"`
	Title       string              `vecty:"prop"`
	Child       actions.DialogChild `vecty:"prop"`
	Waiting     bool                `vecty:"prop"`
	ErrMsg      string              `vecty:"prop"`
	OnOk        actions.OnOkFunc    `vecty:"prop"`
	OnCancel    func()              `vecty:"prop"`
	NoCancelBtn bool                `vecty:"prop"`
}

func (d *Dialog) Connect(s vstore.Store) {
	state := s.State().(*store.DialogState)
	d.Show = state.Show
	d.Title = state.Title
	d.Child = state.Child
	d.Waiting = state.Waiting
	d.ErrMsg = state.ErrMsg
	d.OnOk = state.OnOk
	d.OnCancel = state.OnCancel
	d.NoCancelBtn = state.NoCancelBtn
}

func (d *Dialog) hide() {
	store.GetDialog().Dispatch(&actions.HideDialog{})
}

func (d *Dialog) onOkBtnClick(e *v.Event) {
	if d.Child == nil {
		return
	}

	if !d.Child.CheckValidity() {
		v.Rerender(d.Child)
		return
	}

	if d.OnOk == nil {
		d.hide()
		return
	}

	go func() {
		store.GetDialog().Dispatch(&actions.SetDialogWaiting{Value: true})
		ok := d.OnOk(d.Child)
		store.GetDialog().Dispatch(&actions.SetDialogWaiting{Value: false})
		if ok {
			d.hide()
		}
	}()
}

func (d *Dialog) onCancelBtnClick(e *v.Event) {
	if d.OnCancel != nil {
		d.OnCancel()
	}
	d.hide()
}

func (d *Dialog) Render() v.ComponentOrHTML {
	footer := elem.Div(
		v.Markup(
			prop.ID("dialog__footer"),
		),
		v.If(d.ErrMsg != "",
			elem.Div(
				v.Markup(
					v.Class("notification", "is-warning"),
				),
				v.Text(d.ErrMsg),
			),
		),

		elem.Div(
			v.Markup(
				v.Class("buttons"),
			),

			elem.Button( // Ok
				v.Markup(
					event.Click(d.onOkBtnClick),
					v.Class("button", "is-primary"),
					v.MarkupIf(d.Waiting, v.Class("is-loading")),
					v.Property("disabled", boolProp(d.Waiting)),
				),
				v.Text("确认"),
			),

			v.If(!d.NoCancelBtn,
				elem.Button( // Cancel
					v.Markup(
						v.Class("button"),
						event.Click(d.onCancelBtnClick),
					),
					v.Text("取消"),
				),
			),
		),
	)

	return elem.Div(
		v.Markup( //modal
			v.ClassMap{"modal": true, "is-active": d.Show},
		),
		elem.Div(
			v.Markup(
				v.Class("modal-background"),
			),
		),

		elem.Div(
			v.Markup(
				v.Class("modal-card"),
			),

			elem.Header(
				v.Markup(
					v.Class("modal-card-head"),
				),

				elem.Paragraph(
					v.Markup(
						v.Class("modal-card-title"),
					),
					v.Text(d.Title),
				),

				elem.Button(
					v.Markup(
						v.Class("delete"),
						event.Click(d.onCancelBtnClick),
					),
				),
			),

			elem.Section(
				v.Markup(
					v.Class("modal-card-body"),
				),
				// content
				d.Child,
			),
			elem.Footer(
				v.Markup(
					v.Class("modal-card-foot"),
				),
				footer,
			),
		),
	)
}
